package com.shrct.businessprocess.customerservice.impl;

import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
import com.shrct.businessprocess.customerservice.RCContractInstallInfo;
import com.shrct.businessprocess.customerservice.RCRequireStatus;
import com.shrct.businessprocess.customerservice.RCRoutineService;
import com.shrct.businessprocess.customerservice.RCRoutineServiceInfo;
import com.shrct.businessprocess.customerservice.RCServiceContractDelegate;
import com.shrct.businessprocess.customerservice.RCServiceContractDelegateStatus;
import com.shrct.businessprocess.customerservice.impl.RCContractInstallInfoImpl;
import com.shrct.businessprocess.customerservice.impl.RCRoutineServiceInfoImpl;
import com.shrct.businessprocess.customerservice.proxy.RCServiceContractDelegateProxy;
import com.shrct.businessprocess.organization.RCEmployee;
import com.shrct.businessprocess.organization.RCEnterprise;
import com.shrct.businessprocess.organization.impl.RCEmployeeImpl;
import com.shrct.businessprocess.organization.impl.RCEnterpriseImpl;
import com.shrct.businessprocess.product.RCLogicProduct;
import edu.fudan.langlab.domain.statemachine.ModelObjectLogService;
import edu.fudan.mylang.pf.BaseModelObject;
import edu.fudan.mylang.pf.IGenericQuery;
import java.util.Collection;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.hibernate.annotations.DiscriminatorOptions;

@Entity
@DiscriminatorValue("RCSERVICECONTRACTDELEGATE_TYPE")
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(length = 64)
@Table(name = "rcservicecontractdelegate")
public abstract class RCServiceContractDelegateImpl extends BaseModelObject implements RCServiceContractDelegate {
  public RCServiceContractDelegateImpl() {
    super();
  }
  
  private RCServiceContractDelegateStatus Status;
  
  public RCServiceContractDelegateStatus getStatus() {
    return this.Status;
  }
  
  private ModelObjectLogService getModelObjectLogService() {
    return getBeanFactory().getBean(ModelObjectLogService.class);
  }
  
  private void _start() {
    
    this.installInfo.start();
    this.routineServiceInfo.start();
    Status=RCServiceContractDelegateStatus.initialized;
  }
  
  public void start() {
    if(Status==null){
    	_start();
    	getModelObjectLogService().createLog(this,"Status","Start");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCServiceContractDelegateEventsManager.class).fireStarted(this);					
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException("allready started");
    }
  }
  
  private void _update(final Procedure1<? super RCServiceContractDelegate> preInit) {
    
    preInit.apply(this);
  }
  
  public void update(final Procedure1<? super RCServiceContractDelegate> preInit) {
    if(Status==RCServiceContractDelegateStatus.initialized){
    	_update(preInit);
    	getModelObjectLogService().createLog(this,"Status","update");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCServiceContractDelegateEventsManager.class).fireUpdate(this,preInit);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void _setInstallRequirement(final RCRequireStatus req) {
    
    boolean _matched = false;
    if (!_matched) {
      if (Objects.equal(req,RCRequireStatus.required)) {
        _matched=true;
        this.installInfo.setAsRequired();
      }
    }
    if (!_matched) {
      if (Objects.equal(req,RCRequireStatus.notRequired)) {
        _matched=true;
        this.installInfo.setAsNotRequired();
      }
    }
    if (!_matched) {
      if (Objects.equal(req,RCRequireStatus.unknown)) {
        _matched=true;
        this.installInfo.cancel();
      }
    }
  }
  
  public void setInstallRequirement(final RCRequireStatus req) {
    if(Status==RCServiceContractDelegateStatus.initialized){
    	_setInstallRequirement(req);
    	getModelObjectLogService().createLog(this,"Status","setInstallRequirement");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCServiceContractDelegateEventsManager.class).fireSetInstallRequirement(this,req);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void _setRoutineServiceRequirement(final RCRequireStatus req) {
    
    boolean _matched = false;
    if (!_matched) {
      if (Objects.equal(req,RCRequireStatus.required)) {
        _matched=true;
        this.routineServiceInfo.setAsRequired();
      }
    }
    if (!_matched) {
      if (Objects.equal(req,RCRequireStatus.notRequired)) {
        _matched=true;
        this.routineServiceInfo.setAsNotRequired();
      }
    }
    if (!_matched) {
      if (Objects.equal(req,RCRequireStatus.unknown)) {
        _matched=true;
        this.routineServiceInfo.cancel();
      }
    }
  }
  
  public void setRoutineServiceRequirement(final RCRequireStatus req) {
    if(Status==RCServiceContractDelegateStatus.initialized){
    	_setRoutineServiceRequirement(req);
    	getModelObjectLogService().createLog(this,"Status","setRoutineServiceRequirement");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCServiceContractDelegateEventsManager.class).fireSetRoutineServiceRequirement(this,req);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  public Boolean isInitialized() {
    return com.shrct.businessprocess.customerservice.RCServiceContractDelegateStatus.initialized==Status;
  }
  
  private String projectId;
  
  public String getProjectId() {
    return this.projectId;
  }
  
  public RCServiceContractDelegate setProjectId(final String projectId) {
    this.projectId = projectId;
    return this;			
    
  }
  
  private String projectName;
  
  public String getProjectName() {
    return this.projectName;
  }
  
  public RCServiceContractDelegate setProjectName(final String projectName) {
    this.projectName = projectName;
    return this;			
    
  }
  
  private String contractId;
  
  public String getContractId() {
    return this.contractId;
  }
  
  public RCServiceContractDelegate setContractId(final String contractId) {
    this.contractId = contractId;
    return this;			
    
  }
  
  private String customerLink;
  
  public String getCustomerLink() {
    return this.customerLink;
  }
  
  public RCServiceContractDelegate setCustomerLink(final String customerLink) {
    this.customerLink = customerLink;
    return this;			
    
  }
  
  private String customerLinkPhone;
  
  public String getCustomerLinkPhone() {
    return this.customerLinkPhone;
  }
  
  public RCServiceContractDelegate setCustomerLinkPhone(final String customerLinkPhone) {
    this.customerLinkPhone = customerLinkPhone;
    return this;			
    
  }
  
  private String customerLinkMail;
  
  public String getCustomerLinkMail() {
    return this.customerLinkMail;
  }
  
  public RCServiceContractDelegate setCustomerLinkMail(final String customerLinkMail) {
    this.customerLinkMail = customerLinkMail;
    return this;			
    
  }
  
  private String comment;
  
  public String getComment() {
    return this.comment;
  }
  
  public RCServiceContractDelegate setComment(final String comment) {
    this.comment = comment;
    return this;			
    
  }
  
  @JoinColumn(name = "customer_id")
  @ManyToOne(targetEntity = RCEnterpriseImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCEnterprise customer;
  
  public RCEnterprise getCustomer() {
    return this.customer;
  }
  
  public RCServiceContractDelegate setCustomer(final RCEnterprise customer) {
    this.customer = customer;
    return this;			
    
  }
  
  @JoinColumn(name = "businessMan_id")
  @ManyToOne(targetEntity = RCEmployeeImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCEmployee businessMan;
  
  public RCEmployee getBusinessMan() {
    return this.businessMan;
  }
  
  public RCServiceContractDelegate setBusinessMan(final RCEmployee businessMan) {
    this.businessMan = businessMan;
    return this;			
    
  }
  
  @JoinColumn(name = "majorSales_id")
  @ManyToOne(targetEntity = RCEmployeeImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCEmployee majorSales;
  
  public RCEmployee getMajorSales() {
    return this.majorSales;
  }
  
  public RCServiceContractDelegate setMajorSales(final RCEmployee majorSales) {
    this.majorSales = majorSales;
    return this;			
    
  }
  
  @JoinColumn(name = "installInfo_id")
  @OneToOne(targetEntity = RCContractInstallInfoImpl.class, cascade = CascadeType.ALL)
  private RCContractInstallInfo installInfo;
  
  public RCContractInstallInfo getInstallInfo() {
    return this.installInfo;
  }
  
  public RCServiceContractDelegate setInstallInfo(final RCContractInstallInfo installInfo) {
    this.installInfo = installInfo;
    return this;			
    
  }
  
  @JoinColumn(name = "routineServiceInfo_id")
  @OneToOne(targetEntity = RCRoutineServiceInfoImpl.class, cascade = CascadeType.ALL)
  private RCRoutineServiceInfo routineServiceInfo;
  
  public RCRoutineServiceInfo getRoutineServiceInfo() {
    return this.routineServiceInfo;
  }
  
  public RCServiceContractDelegate setRoutineServiceInfo(final RCRoutineServiceInfo routineServiceInfo) {
    this.routineServiceInfo = routineServiceInfo;
    return this;			
    
  }
  
  public String getEntityName() {
    String _plus = (this.contractId + "[");
    String _plus_1 = (_plus + this.projectId);
    String _plus_2 = (_plus_1 + "]");
    return _plus_2;
  }
  
  public Collection<RCRoutineService> getServiceContracts() {
    IGenericQuery<RCRoutineService> query=getObjectFactory().createGenericQuery(RCRoutineService.class,"select e from com.shrct.businessprocess.customerservice.impl.RCRoutineServiceImpl as e   where ((e.projectInfo) = (:this)) and  e.active = 1      ").setParameter("this",this);
    Collection<RCRoutineService> _list = query.list();
    return _list;
  }
  
  public Boolean isReady4RoutineService() {
    boolean _or = false;
    RCRequireStatus _requireInstall = this.installInfo.getRequireInstall();
    boolean _equals = Objects.equal(_requireInstall, RCRequireStatus.notRequired);
    if (_equals) {
      _or = true;
    } else {
      boolean _and = false;
      RCRequireStatus _requireInstall_1 = this.installInfo.getRequireInstall();
      boolean _equals_1 = Objects.equal(_requireInstall_1, RCRequireStatus.required);
      if (!_equals_1) {
        _and = false;
      } else {
        Boolean _isFinish = this.installInfo.isFinish();
        _and = (_equals_1 && (_isFinish).booleanValue());
      }
      _or = (_equals || _and);
    }
    return Boolean.valueOf(_or);
  }
  
  public Collection<RCLogicProduct> getUngroupedShippingList() {
    List<RCLogicProduct> _xblockexpression = null;
    {
      IGenericQuery<RCRoutineService> query=getObjectFactory().createGenericQuery(RCRoutineService.class,"select e from com.shrct.businessprocess.customerservice.impl.RCRoutineServiceImpl as e   where (((e.projectInfo.contractId) = (:contractId)) and ((e.projectInfo.projectId) = (:projectId))) and  e.active = 1      ").setParameter("contractId",contractId).setParameter("projectId",projectId);
      Collection<RCRoutineService> _list = query.list();
      final Function1<RCRoutineService,Collection<RCLogicProduct>> _function = new Function1<RCRoutineService,Collection<RCLogicProduct>>() {
          public Collection<RCLogicProduct> apply(final RCRoutineService it) {
            Collection<RCLogicProduct> _products = it.getProducts();
            return _products;
          }
        };
      Iterable<Collection<RCLogicProduct>> _map = IterableExtensions.<RCRoutineService, Collection<RCLogicProduct>>map(_list, _function);
      Iterable<RCLogicProduct> _flatten = Iterables.<RCLogicProduct>concat(_map);
      final List<RCLogicProduct> groupedProducts = IterableExtensions.<RCLogicProduct>toList(_flatten);
      Collection<RCLogicProduct> _shippingList = this.getShippingList();
      final Function1<RCLogicProduct,Boolean> _function_1 = new Function1<RCLogicProduct,Boolean>() {
          public Boolean apply(final RCLogicProduct it) {
            boolean _contains = groupedProducts.contains(it);
            boolean _not = (!_contains);
            return Boolean.valueOf(_not);
          }
        };
      Iterable<RCLogicProduct> _filter = IterableExtensions.<RCLogicProduct>filter(_shippingList, _function_1);
      List<RCLogicProduct> _list_1 = IterableExtensions.<RCLogicProduct>toList(_filter);
      _xblockexpression = (_list_1);
    }
    return _xblockexpression;
  }
  
  public Iterable<RCLogicProduct> getRelatedProducts() {
    Collection<RCLogicProduct> _shippingList = this.getShippingList();
    return _shippingList;
  }
  
  public RCServiceContractDelegateProxy toProxy() {
    com.shrct.businessprocess.customerservice.proxy.RCServiceContractDelegateProxy proxy = new com.shrct.businessprocess.customerservice.proxy.RCServiceContractDelegateProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    proxy.setStatus(this.getStatus().name());
    return proxy;
    
  }
}
